package org.jeecg.modules.engineering.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.constant.CacheConstant;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.SmsTemp;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.StringUtils;
import org.jeecg.common.util.UUIDGenerator;
import org.jeecg.common.util.sms.SmsUtil;
import org.jeecg.modules.engineering.entity.*;
import org.jeecg.modules.engineering.mapper.*;
import org.jeecg.modules.engineering.service.*;
import org.jeecg.modules.engineering.util.EngineeringUtil;
import org.jeecg.modules.engineering.util.HMACSHAHelper;
import org.jeecg.modules.engineering.vo.CollectData;
import org.jeecg.modules.engineering.vo.CollectItem;
import org.jeecg.modules.message.entity.SysMessage;
import org.jeecg.modules.message.service.ISysMessageService;
import org.jeecg.modules.system.entity.SmsEntity;
import org.jeecg.modules.system.util.RestTemplateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.*;

@Slf4j
@Service
public class EquipDataApiServiceImpl implements IEquipDataApiService {

    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private RestTemplateUtil restTemplateUtil;
    @Autowired
    private EquipEventInfoMapper equipEventInfoMapper;
    @Autowired
    private EquipEventInfoMapper equipEventSortMapper;
    @Autowired
    private EquipCollectRelationMapper equipCollectRelationMapper;
    @Autowired
    private EquipCollectInfoMapper equipCollectInfoMapper;
    @Autowired
    private EquipInfoMapper equipInfoMapper;
    @Autowired
    private IWebSocketSendService webSocketSendService;
    @Autowired
    private IEquipCollectItemDetailService equipCollectItemDetailService;
    @Autowired
    private IEquipCollectTriggerService equipCollectTriggerService;
    @Autowired
    private IEquipEventSortDetailService equipEventSortDetailService;
    @Autowired
    private IEquipEventSortService equipEventSortService;
    @Autowired
    private IEquipCollectInfoService equipCollectInfoService;
    @Autowired
    private IEquipInfoService equipInfoService;
    @Autowired
    private IEquipCollectItemService equipCollectItemService;
    @Autowired
    private EquipEventNoticeTypeMapper equipEventNoticeTypeMapper;
    @Autowired
    private IEquipLinkThingService equipLinkThingService;
    @Autowired
    private EquipDataCollectorTypeMapper equipDataCollectorTypeMapper;

    @Autowired
    private ISysMessageService sysMessageService;

    /**
     * 调用维小保接口获取token
     * @return
     */
    @Override
    public String getYunTiToken() {
        Object tokenObj = redisUtil.get(CommonConstant.YUN_TI_TOKEN);
        String token = null;
        if(tokenObj != null){
            log.info("从redis获取的云梯维小保token信息为:"+tokenObj.toString());
            JSONObject jsonObject = JSONObject.parseObject(tokenObj.toString());
            long expiresTime = jsonObject.getLong("expiresTime");
            if(Instant.now().getEpochSecond() < expiresTime){
                //token未过期，处于有效状态
                token = jsonObject.getString("accessToken");
            }
        }
        if(StringUtils.isEmpty(token)){
            //token为空，调用接口获取token
            Map<String, Object> map= Maps.newHashMap();
            map.put("AppKey",CommonConstant.YUN_TI_APPKEY);
            map.put("AppSecret",CommonConstant.YUN_TI_APPSECRET);
            JSONObject resultJson = restTemplateUtil.postForEntity(map,CommonConstant.YUN_TI_BASEURL+"/api/v1/getToken",null);
            if(resultJson != null  && "0".equals(resultJson.getString("code"))){
                JSONObject data = resultJson.getJSONObject("data");
                data.put("expiresTime",data.getLong("expiresTime") - (60*60*24));
                redisUtil.set(CommonConstant.YUN_TI_TOKEN,data);
                token = data.getString("accessToken");
            }
        }
        log.info("最终获取的token为:"+token);
        if(StringUtils.isEmpty(token)){
            throw new JeecgBootException("获取维小保token信息为空");
        }
        return token;
    }

    @Override
    public JSONObject syncLiftList() {
        Map<String,Object> uriVariables = new HashMap<>();
        uriVariables.put("accessToken",getYunTiToken());
        return restTemplateUtil.postForEntity(null,CommonConstant.YUN_TI_BASEURL+"/api/v1/info/getLiftRegCodes?access_token={accessToken}",uriVariables);
    }

    @Override
    public List<EquipEventInfo> syncListEventByOutCode(EquipInfo info,EquipDataCollector collector,long startTime, long endTime) {

        int pageIndex = 1;
        int pageSize = 10;
        int maxPage = pageIndex;
        Map<String,Object> uriVariables = Maps.newHashMap();
        uriVariables.put("accessToken",getYunTiToken());
        Map<String,Object> paramMap = Maps.newHashMap();
        paramMap.put("pageSize", pageSize);
        paramMap.put("registerCodes", Collections.singletonList(info.getEquipOutCode()));
        paramMap.put("beginTime", startTime);
        paramMap.put("endTime", endTime);
        List<EquipEventInfo> events = new ArrayList<>();
        while (pageIndex <= maxPage){
            paramMap.put("pageIndex",pageIndex);
            pageIndex++;
            try {
                JSONObject resultJson = restTemplateUtil.postForEntity(paramMap,CommonConstant.YUN_TI_BASEURL+"/api/v1/alarm/getLiftHisAlarm?access_token={accessToken}",uriVariables);
                if("0".equals(resultJson.getString("code"))){
                    JSONObject data = resultJson.getJSONObject("data");
                    int total = data.getInteger("total");
                    maxPage = (total - 1)/pageSize + 1;
                    JSONArray lists = data.getJSONArray("list");
                    if(lists == null || lists.size() == 0){
                        return new ArrayList<>();
                    }
                    for (Object list : lists) {
                        JSONObject json = (JSONObject) list;
                        EquipEventInfo eventInfo = new EquipEventInfo();
                        eventInfo.setId(UUIDGenerator.getUUID());
                        eventInfo.setTenantId(info.getTenantId());
                        eventInfo.setProjectId(info.getProjectId());
                        eventInfo.setEventTime(new Date(json.getLong("alarmTime") * 1000));
//                        eventInfo.setHaveVedio(1);
                        eventInfo.setVedioSource(json.getString("alarmCode"));
                        eventInfo.setEventSource(collector.getId());
                        String alarmType = json.getString("alarmType");
                        List<String> haveVideoCode = new ArrayList<>();
                        haveVideoCode.add("1000007");
                        haveVideoCode.add("1000010");
                        haveVideoCode.add("1000050");
                        haveVideoCode.add("1000018");
                        haveVideoCode.add("1000019");
                        if(haveVideoCode.contains(alarmType)){
                            eventInfo.setHaveVedio(1);
                        }else{
                            eventInfo.setHaveVedio(0);
                        }
                        EquipEventSort eventSort = equipEventSortService.getFromRedisByOtherKey(alarmType);
                        eventInfo.setEventSortId(eventSort == null ? alarmType : eventSort.getId());
                        eventInfo.setEquipId(info.getId());
                        eventInfo.setCreateTime(new Date());
                        if(eventSort != null){
                            //设置事件是否需要处理以及事件级别等信息
                            setEventProcess(info, eventInfo, eventSort.getId(),eventSort.getSortName());
                        }
                        events.add(eventInfo);
                    }
                }
            }catch (Exception e){
                e.printStackTrace();
                log.error("同步维小保电梯信息异常：" + e);
                log.error("同步维小保电梯信息异常参数："+ paramMap );
            }
        }
        if(events.size() > 0 ){
            equipEventInfoMapper.insertBatch(events);
        }
        return events;

    }

    private void setEventProcess(EquipInfo info, EquipEventInfo eventInfo, String eventId,String eventName) {
        //根据eventId和小区id获取当前小区的配置
        EquipEventSortDetail eventDetail = equipEventSortDetailService.getFromRedisByOtherKey(info.getProjectId()+"_"+eventId);
        if(eventDetail != null){
            eventInfo.setWarningLevel(eventDetail.getWarningLevel());
            if(CommonConstant.EVENT_NEED_PROCESS.equals(eventDetail.getNeedProcess())){
                //此处可能会发送短信/或者推送消息等
                eventInfo.setProcessStatus(CommonConstant.EVENT_PROCESS_STATUS_WAIT);
                eventInfo.setProcessBy(info.getResponsible());//设置责任人
            }else{
                eventInfo.setProcessStatus(CommonConstant.EVENT_PROCESS_STATUS_NONE);
            }
        }else{
            EquipEventSort eventSort = equipEventSortService.getFromRedisById(eventId);
            if(eventSort != null){
                eventInfo.setWarningLevel(eventSort.getWarningLevel());
            }else{
                eventInfo.setWarningLevel(CommonConstant.EVENT_WARNING_NORMAL);
            }
            eventInfo.setProcessStatus(CommonConstant.EVENT_PROCESS_STATUS_NONE);
        }

        //按最终结果发送短信通知
        try {
            List<String> phones = equipEventNoticeTypeMapper.queryPhoneList(info.getProjectId(),eventId,eventInfo.getWarningLevel()+"");
            if(phones == null || phones.size() == 0){
                log.info("通知人手机号码列表为空");
                return;
            }
            for(String phone : phones){
                log.info("发送短信到"+phone);
                String eventDate = DateUtils.datetimeFormat.format(eventInfo.getEventTime());
                String equipName = info.getEquipName();
                if(StringUtils.isEmpty(eventName)){
                    eventName = equipEventSortMapper.selectNameById(eventId);
                }
                String projectName = equipInfoMapper.selectProjectNameById(info.getProjectId());
                SmsEntity smsEntity = SmsUtil.sendSms(phone, SmsTemp.SMS_175061170,"community",projectName,"equipment",equipName,"event",eventName,"eventTime",eventDate);
                String status = "";
                if (smsEntity.getMessage().equalsIgnoreCase("OK")){
                    status = "1";
                }else {
                    status = "2";
                }
                saveMessage(smsEntity.getContent(),info.getProjectId(),phone,status,info.getTenantId());

                log.info("发送成功");
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("发送通知短信出现异常"+e.toString());
        }
    }

    private void saveMessage(String content, String projectId, String phone, String status, long tenantId){
        SysMessage sysMessage = new SysMessage();
        sysMessage.setId(UUIDGenerator.getUUID());
        sysMessage.setEsType("1");
        sysMessage.setTenantId(tenantId);
        sysMessage.setEsContent(content);
        sysMessage.setProjectId(projectId);
        sysMessage.setEsReceiver(phone);
        sysMessage.setEsTitle("设备报警短信");
        sysMessage.setEsSendStatus(status);
        sysMessage.setEsSendTime(new Date());
        sysMessageService.saveForTenant(sysMessage);
    }

    @Override
    public String getLiftAlarmVedioUrl(String alarmCode, Boolean isHttps) {
        Map<String,Object> uriVariables = Maps.newHashMap();
        uriVariables.put("accessToken",getYunTiToken());
        Map<String,Object> paramMap = Maps.newHashMap();
        paramMap.put("alarmCode",alarmCode);
        paramMap.put("authType","token");
        JSONObject resultJson = restTemplateUtil.postForEntity(paramMap,CommonConstant.YUN_TI_BASEURL+"/api/v1/media/getAlarmvideoAuthorization?access_token={accessToken}",uriVariables);
        if("0".equals(resultJson.getString("code"))){
            JSONObject data = resultJson.getJSONObject("data");
            if(isHttps){
                return data.getString("urlSec");
            }else{
                return data.getString("url");
            }
        }
        throw new JeecgBootException(resultJson.getInteger("code"),resultJson.getString("message"));
    }

    @Override
    public JSONObject getLiftBaseInfo(List<String> lifts) {
        Map<String,Object> uriVariables = Maps.newHashMap();
        uriVariables.put("accessToken",getYunTiToken());
        Map<String,Object> paramMap = Maps.newHashMap();
        paramMap.put("registerCodes",lifts);
        return restTemplateUtil.postForEntity(paramMap,CommonConstant.YUN_TI_BASEURL+"/api/v2/lift/getInfo?access_token={accessToken}",uriVariables);
    }

    @Override
    public String getLiftRealVedioUrl(String registerCode, Boolean isHttps) {
        Map<String,Object> uriVariables = Maps.newHashMap();
        uriVariables.put("accessToken",getYunTiToken());
        Map<String,Object> paramMap = Maps.newHashMap();
        paramMap.put("registerCode",registerCode);
        JSONObject resultJson = restTemplateUtil.postForEntity(paramMap,CommonConstant.YUN_TI_BASEURL+"/api/v2/media/getRealvideoAuthorization?access_token={accessToken}",uriVariables);
        if("0".equals(resultJson.getString("code"))){
            JSONObject data = resultJson.getJSONObject("data");
            JSONArray urls = data.getJSONArray("urls");
            if(isHttps){
                return ((JSONObject)urls.get(0)).getString("httpsUrl");
            }else{
                return ((JSONObject)urls.get(0)).getString("httpUrl");
            }
        }
        throw new JeecgBootException(resultJson.getInteger("code"),resultJson.getString("message"));
    }

    @Override
    public JSONObject getLiftAudioTalkData(String registerCode, Boolean isVideo) {
        Map<String,Object> uriVariables = Maps.newHashMap();
        uriVariables.put("accessToken",getYunTiToken());
        Map<String,Object> paramMap = Maps.newHashMap();
        paramMap.put("registerCode",registerCode);
        paramMap.put("authType","token");
        JSONObject resultJson = restTemplateUtil.postForEntity(paramMap,CommonConstant.YUN_TI_BASEURL+"/api/v1/media/getAudiotalkAuthorization?access_token={accessToken}",uriVariables);
        if("0".equals(resultJson.getString("code"))){
            JSONObject data = resultJson.getJSONObject("data");
            if(isVideo){
                return data.getJSONObject("videoTalkInfo");
            }else{
                return data.getJSONObject("voiceTalkInfo");
            }
        }
        throw new JeecgBootException(resultJson.getInteger("code"),resultJson.getString("message"));
    }

    @Override
    @Async("asyncExecutor")
    @Transactional
    public void acceptEventData(String equipCode, String itemCode, String value, Long collectTime, String registerCode) {
        //从redis中获取equipInfo对象
        EquipInfo info = equipInfoService.getFromRedisByOtherKey("equip_out_code:"+equipCode);
        if(info == null || StringUtils.isEmpty(info.getProjectId())){
            log.info("根据设备编码未找到设备或设备所属小区为空");
            return;
        }
        //根据采集项编码，采集商编码，和小区id查询对应的采集项id，采集商id，小区采集项id
        List<JSONObject> objects = equipCollectRelationMapper.queryDataByCode(itemCode,registerCode);
        if(objects == null || objects.size() == 0 ){
            log.info("未找到当前采集项或者当前小区未配置此采集项");
            return;
        }
        JSONObject obj = objects.get(0);
        String itemId = obj.getString("itemId");
        String code = obj.getString("itemCode");
        String source = obj.getString("collectorId");
        Integer isTrigger = obj.getInteger("isTrigger");

        EquipCollectInfo collectInfo = new EquipCollectInfo();
        collectInfo.setId(UUIDGenerator.getUUID());
        collectInfo.setProjectId(info.getProjectId());
        collectInfo.setTenantId(info.getTenantId());
        collectInfo.setValue(value);
        collectInfo.setItemId(itemId);
        collectInfo.setCollectChannel(source);
        collectInfo.setEquipId(info.getId());
        collectInfo.setCollectTime(new Date(collectTime));
        collectInfo.setIsAccept(1);//为推送接收数据
        collectInfo.setCreateTime(new Date());

        equipCollectInfoService.insertBatch(Collections.singletonList(collectInfo),info.getId());

        boolean changed = changeEquipStatus(info,value,code);
        if(changed){
            //有信息变动，需要更新
            equipInfoMapper.batchUpdate(Collections.singletonList(info));
            equipInfoService.setToRedis(info);
            try{
                //同步设备信息到物管中心
                equipLinkThingService.syncEquipInfo(Collections.singletonList(info));
            }catch (Exception e){
                e.printStackTrace();
                log.error("获取信息推送时更新设备信息到物管中心接口异常"+e);
            }
        }

        if(StringUtils.isEmpty(itemId)){
            log.info("取得采集编号为空,停止触发事件");
            return;
        }
        try{
            EquipDataCollectorType type = equipDataCollectorTypeMapper.getTypeByCollector(info.getSortId(),CommonConstant.LING_THING_CODE);
            JSONObject status = getStstus(type,itemId,value,info,new Date(collectTime));
            if(status != null){
                //把数据上传到物管中心
                JSONArray array = new JSONArray();
                array.add(status);
                equipLinkThingService.postEquipStatus(array);
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("获取信息推送时上传数据到物管中心接口异常"+e);
        }
        //获取触发规则列表
        List<EquipCollectTrigger> triggers = getTriggers(isTrigger,itemId,info.getProjectId());
        if(triggers == null || triggers.size() == 0){
            log.info("取得触发规则为空,停止触发事件");
            return;
        }
        String[] eventArr = EngineeringUtil.getEventByTriggers(triggers,value).split(",");
        if (eventArr.length < 2) {
            log.info("未匹配到触发事件");
            return;
        }
        String eventId = eventArr[0];
        String triggerId = eventArr[1];
        String redisKey = CacheConstant.EVENT_TRIGGER + info.getId() + "_" + itemId;
        Object redisObj = redisUtil.get(redisKey);
        if(!eventId.equals(redisObj)){
            EquipEventInfo eventInfo = new EquipEventInfo();
            eventInfo.setId(UUIDGenerator.getUUID());
            eventInfo.setEquipId(info.getId());
            eventInfo.setHaveVedio(0);
            eventInfo.setEventSortId(eventId);
            eventInfo.setEventTriggerId(triggerId);
            eventInfo.setEventSource(source);
            eventInfo.setEventTime(new Date(collectTime));
            eventInfo.setProjectId(info.getProjectId());
            eventInfo.setTenantId(info.getTenantId());
            eventInfo.setCreateTime(new Date());
            //设置事件是否需要处理以及事件级别等信息
            setEventProcess(info, eventInfo, eventId,null);
            equipEventInfoMapper.insertBatch(Collections.singletonList(eventInfo));
            redisUtil.set(redisKey,eventId);
        }else{
            log.info("当前设备的此事件已经被触发");
        }

    }

    /**
     * 根据采集到的值更新对应的信息
     * info 设备主表
     * value 采集到的值
     * itemId 采集项id
     **/
    private boolean changeEquipStatus(EquipInfo info, String value, String itemCode) {
        if(StringUtils.isEmpty(value)){
            return false;
        }
        Integer status;//status 0为正常 1为异常
        if(CommonConstant.EQUIP_COLLECT_ITEM_0029.equals(itemCode)){
            //此采集项为门禁状态
            //门襟开着(1)为正常状态
            status = value.equals("1")? 0:1;
            if(!status.equals(info.getEquipStatus())){
                info.setEquipStatus(status);
                return true;
            }
        }else if(CommonConstant.EQUIP_COLLECT_ITEM_0024.equals(itemCode)){
            //此采集项为井盖状态
            //井盖关着(0)为正常状态
            status = value.equals("0")? 0:1;
            if(!status.equals(info.getEquipStatus())){
                info.setEquipStatus(status);
                return true;
            }
        }else if(CommonConstant.EQUIP_COLLECT_ITEM_0025.equals(itemCode)){
            //此采集项为水阀状态
            //水阀开着(1)为正常状态
            status = value.equals("1")? 0:1;
            if(!status.equals(info.getEquipStatus())){
                info.setEquipStatus(status);
                return true;
            }
        }
        return false;
    }


    @Async("asyncExecutor")
    public void asyncCollectData(List<CollectData> resultData) {
        log.info("start executeAsync");
        Date nowDate = new Date();
        String nowDateString = DateUtils.date2Str(nowDate,new SimpleDateFormat("yyyyMM"));
        List<EquipCollectInfo> infos = new ArrayList<>();
        List<EquipEventInfo> eventInfos = new ArrayList<>();
        List<String> deleteEquipList = new ArrayList<>();
        Map<String,String> redisEventMap = new HashMap<>();
        Map<String,EquipDataCollectorType> types = new HashMap<>();
        List<EquipDataCollectorType> typeList = equipDataCollectorTypeMapper.selectListAll();
        if(typeList != null && typeList.size() > 0){
            for (EquipDataCollectorType type : typeList){
                types.put(type.getSortId()+"-"+type.getCollectorCode(),type);
            }
        }

        List<CollectItem> collectItemList = new ArrayList<>(); //站内推送消息用
        List<EquipInfo> updateInfos = new ArrayList<>();
        JSONArray statusArray = new JSONArray();
        long startTime = System.currentTimeMillis();
        for(CollectData data : resultData){

            //若检测项返回的数据列表为空，则不处理此设备的采集信息
            List<CollectItem> collectItems = data.getDataItem();
            if(collectItems == null || collectItems.size() == 0){
                continue;
            }
            //根据外包商code获取对应的设备信息
            String outEquipCode = data.getEquipCode();
            //从redis中根据编号获取设备信息
            EquipInfo info = equipInfoService.getFromRedisByOtherKey("equip_out_code:"+outEquipCode);
            if(info == null){
                continue;
            }
            deleteEquipList.add(info.getId());
            boolean needAdd = true;
            for(CollectItem collectItem : collectItems){
                EquipCollectItem item = equipCollectItemService.getFromRedisByOtherKey(collectItem.getItem());
                if(item == null){
                    log.info("采集项编码：["+collectItem.getItem()+"]在系统中不存在");
                    continue;
                }

                EquipCollectInfo collectInfo = new EquipCollectInfo();
                collectInfo.setId(UUIDGenerator.getUUID());
                collectInfo.setCollectTime(collectItem.getTime());
                collectInfo.setEquipId(info.getId());
                collectInfo.setTenantId(info.getTenantId());
                collectInfo.setProjectId(info.getProjectId());
                collectInfo.setItemId(item.getId());
                collectInfo.setCollectChannel(info.getCollectorId());
                collectInfo.setValue(collectItem.getValue());
                collectInfo.setIsAccept(0);
                collectInfo.setCreateTime(nowDate);
                collectInfo.setCreateBy(null);
                infos.add(collectInfo);
//
                boolean changed = changeEquipStatus(info,collectItem.getValue(),item.getCollectCode());
                if(changed && needAdd){
                    //有信息变动，并且未添加过
                    updateInfos.add(info);
                    needAdd = false;
                }

                //获取物管中心对应的类型
                EquipDataCollectorType type = types.get(info.getSortId()+"-"+CommonConstant.LING_THING_CODE);
                JSONObject status = getStstus(type,item.getId(),collectItem.getValue(),info,collectItem.getTime());
                if(status != null){
                    statusArray.add(status);
                }

                //获取触发规则列表
                List<EquipCollectTrigger> triggers = getTriggers(item.getIsTrigger(),item.getId(),info.getProjectId());
                if(triggers == null || triggers.size() == 0){
                    continue;
                }
                triggerItem(redisEventMap,eventInfos,item.getId(),triggers,collectItem,info,collectItemList);
            }
        }
        log.info("总消耗的时间为："+(System.currentTimeMillis()-startTime));
        //将检测设备的检测表数据先删除，后续统一批量增加
        if(updateInfos.size() > 0 ){
            log.info("需要更新的设备数量为:"+updateInfos.size());
            equipInfoMapper.batchUpdate(updateInfos);
            for (EquipInfo equipInfo :updateInfos){
                equipInfoService.setToRedis(equipInfo);
            }
        }

        //将检测设备的检测表数据先删除，后续统一批量增加
        if(deleteEquipList.size() > 0 ){
            equipCollectInfoMapper.deleteByEquipIds(deleteEquipList);
        }

        //把检测的最新数据存入检测表以及快照表
        if(infos.size() > 0){
            equipCollectInfoMapper.insertBatch(nowDateString,infos);
            equipCollectInfoMapper.insertBatch("",infos);
            //给前端推送消息
//            Map<String,CollectItem> collectItemMap = collectItemList.stream().collect(Collectors.toMap(CollectItem::getProjectId, Function.identity()));
//            collectItemMap.forEach((k,v)->{
//                if (v.getEventWarningMiddleFlg() || v.getEventWarningMaxFlg()){
//                   /*List<SysUser> userList =  userMapper.findUserByProjectId(k);
//                   StringBuilder sb = new StringBuilder();
//                   if (userList.size() > 0 ){
//                      userList.forEach(sysUser -> {
//                          sb.append(sysUser.getId());
//                          sb.append(";");
//                      });
//                   }*/
//                    webSocketSendService.apiSend("e9ca23d68d884d4ebb19d07889727dae",CommonConstant.SOCKET_EVENT_INFO,v.getTenantId());
//                }
//            });


        }

        //把触发事件批量存入事件表
        if(eventInfos.size() > 0){
            equipEventInfoMapper.insertBatch(eventInfos);
        }
        //开始把触发事件存入redis
        if(redisEventMap.size() > 0){
            for (Map.Entry<String,String> entry : redisEventMap.entrySet()){
                redisUtil.set(entry.getKey(),entry.getValue());
            }
        }
        try{
            if(updateInfos.size() > 0 ){
                //同步设备信息到物管中心
                equipLinkThingService.syncEquipInfo(updateInfos);
            }
            if(statusArray.size() > 0 ){
                //把数据上传到物管中心
                equipLinkThingService.postEquipStatus(statusArray);
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("采集数据同步更新信息到物管中心异常"+e);
        }
        log.info("end executeAsync");
    }

    /**
     * 根据供应商分类关系和采集项id获取需要上传到物管中心设备属性
     * @param type
     * @param collectId
     * @return
     */
    private JSONObject getStstus(EquipDataCollectorType type,String collectId,String value,EquipInfo info,Date collectTime){
        if(type == null || StringUtils.isBlank(collectId) || StringUtils.isBlank(info.getSignKey())){
            return null;
        }
        String sendValue = null;
        if(collectId.equals(type.getCollectId())){
            if(CommonConstant.LING_THING_TYPE_00003.equals(type.getCollectorType())){
                sendValue = value;
            }else if(CommonConstant.LING_THING_TYPE_00004.equals(type.getCollectorType())){
                sendValue = value;
            }else if(CommonConstant.LING_THING_TYPE_00005.equals(type.getCollectorType())){
                sendValue = value;
            }else if(CommonConstant.LING_THING_TYPE_00006.equals(type.getCollectorType())){
                sendValue = value;
            }else if(CommonConstant.LING_THING_TYPE_00007.equals(type.getCollectorType())){
                sendValue = value;
            }
        }
        if(sendValue == null){
            return null;
        }
        JSONObject status = new JSONObject(new TreeMap<>());
        status.put("Uid",info.getEquipCode());
        status.put("Battery",0);
        status.put("Type",type.getCollectorType());
        status.put("UpRssi",0);
        status.put("UploadTime",DateUtils.datetimeFormat.format(collectTime));
        JSONObject data = new JSONObject(new TreeMap<>());
        data.put("Status",sendValue);
        data.put("Sensor_Time",DateUtils.datetimeFormat.format(collectTime));
        status.put("UploadData",data);
        String sign = HMACSHAHelper.getSHA1Signature(status.toJSONString().getBytes(),info.getSignKey().getBytes());
        status.put("Signature",sign);
        return status;
    }
    private List<EquipCollectTrigger> getTriggers(Integer isTrigger,String itemId,String projectId){
        List<EquipCollectTrigger> triggers = null;
        if(CommonConstant.EVENT_TRIGGER_TRUE.equals(isTrigger)){
            //系统级别为触发事件，则获取系统级别的触发规则
            triggers = equipCollectTriggerService.getFromRedisById(itemId);
        }
        //查询当前小区是否配置了自定义的事件触发规则
        EquipCollectItemDetail itemDetail = equipCollectItemDetailService.getFromRedisByOtherKey(projectId+"_"+itemId);
        if(itemDetail != null && CommonConstant.EVENT_TRIGGER_TRUE.equals(itemDetail.getIsTrigger())){
            //当前小区已配置触发规则并且为触发事件
            //校验当前检测项是否关联了事件触发
            triggers = equipCollectTriggerService.getFromRedisById(itemDetail.getId());
        }
        return triggers;
    }
    /**
     * 处理单个item的事件触发操作
     */
    private void triggerItem(Map<String,String> redisEventMap,List<EquipEventInfo> eventInfos,String itemId,List<EquipCollectTrigger> triggers,CollectItem collectItem ,EquipInfo equipInfo,List<CollectItem> collectItemList){

        String[] eventArr = EngineeringUtil.getEventByTriggers(triggers,collectItem.getValue()).split(",");
        if (eventArr.length < 2 ) {
            log.info("未匹配到触发事件");
            return;
        }
        String eventId = eventArr[0];
        String triggerId = eventArr[1];
        String redisKey = CacheConstant.EVENT_TRIGGER + equipInfo.getId() + "_" + itemId;
        if(eventId == null){
            //为检测到需要触发的事件，若reids中存在已触发事件，则清空（或者直接删除redis中对应的key）
            redisUtil.del(redisKey);
        }else{
            //从reids中获取当前设备的当前item触发的事件，若事件id相同，则忽略，若不相同，则触发事件
            Object redisObj = redisUtil.get(redisKey);

            if(!eventId.equals(redisObj)){
                //防止在存入事件的时候出现异常，导致redis数据和数据库数据不匹配，此时不直接存入redis
                redisEventMap.put(redisKey,eventId);
                //触发事件
                EquipEventInfo eventInfo = new EquipEventInfo();
                eventInfo.setId(UUIDGenerator.getUUID());
                eventInfo.setCreateBy(null);
                eventInfo.setCreateTime(new Date());
                eventInfo.setTenantId(equipInfo.getTenantId());
                eventInfo.setProjectId(equipInfo.getProjectId());
                eventInfo.setEquipId(equipInfo.getId());
                eventInfo.setEventSortId(eventId);
                eventInfo.setEventTriggerId(triggerId);
                eventInfo.setEventSource(CommonConstant.COLLECTOR_SYSTEM_ID);
                eventInfo.setEventTime(collectItem.getTime());
                eventInfo.setHaveVedio(0);
                eventInfos.add(eventInfo);
                //设置事件是否需要处理以及事件级别等信息
                setEventProcess(equipInfo,eventInfo,eventId,null);
                //判断事件警报等级
                Integer redisEventSort = eventInfo.getWarningLevel();
                if (redisEventSort != null){
                    collectItem.setTenantId(eventInfo.getTenantId());
                    collectItem.setProjectId(eventInfo.getProjectId());
                    if (redisEventSort.equals(CommonConstant.EVENT_WARNING_NORMAL)){
                        collectItem.setEventWarningNormalFlg(true);
                    } else if (redisEventSort.equals(CommonConstant.EVENT_WARNING_MIN)){
                        collectItem.setEventWarningMinFlg(true);
                    } else if (redisEventSort.equals(CommonConstant.EVENT_WARNING_MIDDLE)){
                        collectItem.setEventWarningMiddleFlg(true);
                    } else if (redisEventSort.equals(CommonConstant.EVENT_WARNING_MAX)){
                        collectItem.setEventWarningMaxFlg(true);
                    }
                    collectItemList.add(collectItem);
                }
            }
        }
    }

}
